commonlibsse_ng\re\s/
Setting.rs1use crate::re::Color::Color;
8use crate::re::MemoryManager::free;
9use crate::re::offsets_rtti::RTTI_Setting;
10use crate::re::offsets_vtable::VTABLE_Setting;
11use crate::rel::id::VariantID;
12use core::ffi::{CStr, c_char};
13use core::{fmt, ptr};
14
15#[repr(C)]
21#[derive(Clone)]
22pub struct Setting {
23 pub vtable: *const SettingVtbl,
24 data: Data,
25 name: *mut c_char,
26}
27const _: () = {
28 assert!(core::mem::offset_of!(Setting, data) == 0x08);
29 assert!(core::mem::offset_of!(Setting, name) == 0x10);
30 assert!(core::mem::size_of::<Setting>() == 0x18);
31};
32
33impl Default for Setting {
34 fn default() -> Self {
35 unsafe { core::mem::zeroed() }
36 }
37}
38
39impl fmt::Debug for Setting {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.debug_struct("Setting")
42 .field("vtable", &self.vtable)
43 .field("name", &self.get_name().map(|name| name.to_str().unwrap_or("Invalid Name")))
44 .field("data", &self.get_value())
45 .finish()
46 }
47}
48
49impl PartialEq for Setting {
50 fn eq(&self, other: &Self) -> bool {
51 self.get_type() == other.get_type() && self.get_value() == other.get_value()
52 }
53}
54
55#[repr(u32)]
57#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
58pub enum Type {
59 #[default]
60 Unknown = 0,
61 Bool,
62 Float,
63 SignedInteger,
64 Color,
65 String,
66 UnsignedInteger,
67}
68
69#[derive(Default, Clone, PartialEq)]
71pub enum SettingValue<'a> {
72 Bool(bool),
73 Float(f32),
74 SignedInteger(i32),
75 Color(Color),
76 String(&'a CStr),
78 UnsignedInteger(u32),
79 #[default]
80 Unknown,
81}
82
83impl fmt::Debug for SettingValue<'_> {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
87 Self::Float(arg0) => f.debug_tuple("Float").field(arg0).finish(),
88 Self::SignedInteger(arg0) => f.debug_tuple("SignedInteger").field(arg0).finish(),
89 Self::Color(arg0) => f.debug_tuple("Color").field(arg0).finish(),
90 Self::String(arg0) => f.debug_tuple("String").field(&arg0.to_str()).finish(),
91 Self::UnsignedInteger(arg0) => f.debug_tuple("UnsignedInteger").field(arg0).finish(),
92 Self::Unknown => write!(f, "Unknown"),
93 }
94 }
95}
96
97#[repr(C)]
101#[derive(Clone, Copy)]
102union Data {
103 pub b: bool,
104 pub f: f32,
105 pub i: i32,
106 pub r: Color,
107 pub s: *const c_char,
108 pub u: u32,
109}
110const _: () = assert!(core::mem::size_of::<Data>() == 0x8);
111
112impl Setting {
113 pub const RTTI: VariantID = RTTI_Setting;
115
116 pub const VTABLE: [VariantID; 1] = VTABLE_Setting;
118
119 #[inline]
121 pub const fn is_managed(&self) -> bool {
122 !self.name.is_null() && unsafe { self.name.read() } == b'S' as i8
123 }
124
125 #[inline]
127 pub const fn get_type(&self) -> Type {
128 match unsafe { self.name.read() } as u8 {
129 b'b' => Type::Bool,
130 b'f' => Type::Float,
131 b'i' => Type::SignedInteger,
132 b'r' => Type::Color,
133 b's' | b'S' => Type::String,
134 b'u' => Type::UnsignedInteger,
135 _ => Type::Unknown,
136 }
137 }
138
139 #[inline]
146 pub const fn get_name(&self) -> Option<&CStr> {
147 if self.name.is_null() {
148 return None;
149 }
150 unsafe { Some(CStr::from_ptr(self.name)) }
151 }
152
153 #[inline]
155 pub const fn get_value(&self) -> SettingValue<'_> {
156 if self.name.is_null() {
157 return SettingValue::Unknown;
158 }
159
160 unsafe {
161 match self.get_type() {
162 Type::Bool => SettingValue::Bool(self.data.b),
163 Type::Float => SettingValue::Float(self.data.f),
164 Type::SignedInteger => SettingValue::SignedInteger(self.data.i),
165 Type::Color => SettingValue::Color(self.data.r),
166 Type::String => {
167 let s = self.data.s;
168 if s.is_null() {
169 SettingValue::Unknown
170 } else {
171 SettingValue::String(CStr::from_ptr(s))
172 }
173 }
174 Type::UnsignedInteger => SettingValue::UnsignedInteger(self.data.u),
175 Type::Unknown => SettingValue::Unknown,
176 }
177 }
178 }
179}
180
181impl Drop for Setting {
182 fn drop(&mut self) {
183 ((unsafe { &*self.vtable }).CxxDrop)(self);
184 }
185}
186
187#[repr(C)]
189pub struct SettingVtbl {
190 pub CxxDrop: fn(this: &mut Setting),
191 pub Unk_01: fn(this: &mut Setting) -> bool,
192}
193
194impl Default for SettingVtbl {
195 #[inline]
196 fn default() -> Self {
197 Self::new()
198 }
199}
200
201impl SettingVtbl {
202 #[inline]
203 pub const fn new() -> Self {
204 fn CxxDrop(this: &mut Setting) {
205 if this.is_managed() {
206 unsafe { free(this.name.cast()) };
207 this.name = ptr::null_mut();
208 }
209 }
210 const fn Unk_01(_this: &mut Setting) -> bool {
211 false
212 }
213 Self { CxxDrop, Unk_01 }
214 }
215}